Skip to main content

time.h

time_t

time_t is a type alias for time, which can be thought of as International Standard Time UTC. it may be either a floating point number or an integer, usually an integer on Unix systems.

On many systems, time_t indicates the number of seconds since the time epoch, which for Unix is the minute and second of January 1, 1970 in International Standard Time UTC. time_t, if negative, indicates the time before the time epoch.

time_t is generally an alias for a 32-bit or 64-bit integer type, depending on the current system. If it is a 32-bit signed integer, time_t can represent time up to 19 Jan 2038 03:14:07 UTC; if it is a 32-bit unsigned integer, it represents time up to 2106. If it is a 64-bit signed integer, it can represent the time range -293 billion years to +293 billion years.

struct tm

struct tm is a data structure that holds the various components of time, such as hours, minutes, seconds, days, months, years, etc. Here is how it is structured.

struct tm {
int tm_sec; // number of seconds [0, 60]
int tm_min; // minutes [0, 59]
int tm_hour; // hours [0, 23]
int tm_mday; // number of days in the month [1, 31]
int tm_mon; // month [0, 11], January is represented by 0
int tm_year; // number of years until 1900
int tm_wday; // the day of the week [0, 6], with 0 for Sunday
int tm_yday; // the number of days until January 1 [0, 365]
int tm_isdst; // whether daylight saving time is used, 1 means it is, 0 means it is not
};

time()

The `time() function returns the number of seconds that have elapsed since the time epoch.

time_t time(time_t* returned_value);

`time() accepts a time_t pointer as an argument and the return value is written to the pointer address. The argument can be a null pointer NULL.

The return value of time()` is the current time of type time_t. The time()` function returns -1 if the computer cannot provide the current number of seconds, or if the return value is too large to be represented by a time_t type.

time_t now;

// Write one
now = time(NULL);

// write two
time(&now);

The above example shows two ways of writing the current time into the variable now.

To find out the exact time taken by an operation, you need to call time() twice and then subtract the return value from the two.

time_t begin = time(NULL);

// ... Execute some operation

time_t end = time(NULL);

printf("%d\n", end - begin);

Note that the above method is only accurate to the second.

ctime()

`ctime() is used to output a value of type time_t directly into human-readable format.

char* ctime( time_t const * time_value );

The argument to `ctime() is a time_t pointer, which returns a string pointer. The format of the string is something like "Sun Jul 4 04:02:48 1976\n\0", with a newline and a string termination marker at the end.

Here is an example.

time_t now; 

now = time(NULL);

// output Sun Feb 28 18:47:25 2021
printf("%s", ctime(&now));

Note that ctime() will automatically add a newline to the end of the string.

localtime(), gmtime()

The localtime() function is used to convert a time of type time_t, into a struct tm structure for the current time zone.

The gmtime() function is used to convert a time of type time_t to a struct tm structure of UTC time.

The difference between them is the return value, the former is the local time and the latter is the UTC time.

struct tm* localtime(const time_t* timer);
struct tm* gmtime(const time_t* timer);

Here is an example.

time_t now = time(NULL);

// output Local: Sun Feb 28 20:15:27 2021
printf("Local: %s", asctime(localtime(&now)));

// output UTC : Mon Mar 1 04:15:27 2021
printf("UTC : %s", asctime(gmtime(&now)));

asctime()

The asctime() function is used to take a struct tm structure and output it directly into human-readable format. The function will automatically add a newline character to the end of the output.

See the previous section for an example of how to do this.

mktime()

The `mktime() function is used to convert a struct tm structure into a time_t value.

time_t mktime(struct tm* tm_ptr);

The argument to mktime() is a struct tm pointer.

`mktime() automatically sets the tm_wday attribute and tm_yday attribute inside the struct tm structure, the developer does not have to fill in these two attributes himself. So, this function is commonly used to get the day of the week (tm_wday) at a given time.

The tm_isdst attribute of the struct tm structure can also be set to -1, allowing mktime() to decide whether daylight saving time should be used.

Here is an example.

struct tm some_time = {
.tm_year=82, // the number of years until 1900
.tm_mon=3, // month [0, 11]
.tm_mday=12, // number of days [1, 31]
.tm_hour=12, // hours [0, 23]
.tm_min=00, // minutes [0, 59]
.tm_sec=04, // seconds [0, 60]
.tm_isdst=-1, // daylight saving time
};

time_t some_time_epoch;
some_time_epoch = mktime(&some_time);

// output Mon Apr 12 12:00:04 1982
printf("%s", ctime(&some_time_epoch));

// output Is DST: 0
printf("Is DST: %d\n", some_time.tm_isdst);

difftime()

`difftime() is used to calculate the difference between two times. on Unix systems, the difference in seconds is obtained by directly subtracting the two time_t values, but it is better to use this function for program portability.

double difftime( time_t time1, time_t time2 );

The `difftime() function takes two times of type time_t as arguments, calculates the difference between time1 - time2, and converts the result to seconds.

Note that its return value is of type double.

#include <stdio.h>
#include <time.h>

int main(void) {
struct tm time_a = {
.tm_year=82,
.tm_mon=3,
.tm_mday=12,
.tm_hour=4,
.tm_min=00,
.tm_sec=04,
.tm_isdst=-1,
};

struct tm time_b = {
.tm_year=120,
.tm_mon=10,
.tm_mday=15,
.tm_hour=16,
.tm_min=27,
.tm_sec=00,
.tm_isdst=-1,
};

time_t cal_a = mktime(&time_a);
time_t cal_b = mktime(&time_b);

double diff = difftime(cal_b, cal_a);

double years = diff / 60 / 60 / 24 / 365.2425;

// output 1217996816.000000 seconds (38.596783 years) between events
printf("%f seconds (%f years) between events\n", diff, years);
}

In the above example, the exact length of a year, 365.2425 days, is used to try to be as accurate as possible when converting years, so that the effect of leap years can be offset.

strftime()

The `strftime() function is used to convert the struct tm structure to a string of the specified format and copy it to the specified address.

size_t strftime(
char* str,
size_t maxsize,
const char* format,
const struct tm* timeptr
)

strftime() accepts four arguments.

  • First argument: a pointer to the target string.
  • Second argument: the maximum length that the target string can accept.
  • Third argument: the format string.
  • Fourth argument: struct tm structure.

The strftime() function returns the length of the copied string if the execution succeeds (converts and copies); if it fails, it returns -1.

Here is an example.

#include <stdio.h>
#include <time.h>

int main(void) {
char s[128];
time_t now = time(NULL);

// %c: local time
strftime(s, sizeof s, "%c", localtime(&now));
puts(s); // Sun Feb 28 22:29:00 2021

// %A: the name of the full day of the week
// %B: the full month name
// %d: number of days in the month
strftime(s, sizeof s, "%A, %B %d", localtime(&now));
puts(s); // Sunday, February 28

// %I: hours (12-hour format)
// %M: minutes
// %S: number of seconds
// %p: AM or PM
strftime(s, sizeof s, "It's %I:%M:%S %p", localtime(&now));
puts(s); // It's 10:29:00 PM

// %F: ISO 8601 yyyy-mm-dd format
// %T: ISO 8601 hh:mm:ss format
// %z: ISO 8601 time zone
strftime(s, sizeof s, "ISO 8601: %FT%T%z", localtime(&now));
puts(s); // ISO 8601: 2021-02-28T22:29:00-0800
}

The following are commonly used format placeholders.

  • %%: Outputs the % character.
  • %a: short form of the day of the week, in local time.
  • %A: the full form of the day of the week, in local time.
  • %b: short form of the month in local time.
  • %B: Full form of the month in local time.
  • %c: date and time, using "%x %X".
  • %d: number of days in the month (01-31).
  • %H: hour, using the 24-hour format (00-23).
  • %I: hour, using the 12-hour system (00-12).
  • %J: days of the year (001-366).
  • %m: number of months (01-12).
  • %M: minutes (00-59).
  • %P: AM or PM.
  • %R: equivalent to "%H:%M".
  • %S: Seconds (00-61).
  • %U: day of the week of the year (00-53), with Sunday as day 1.
  • %w: day of the week, with Sunday as day 0.
  • %W: day of the week (00-53) of the year, with Monday as day 1.
  • %x: date of the complete year in local time.
  • %X: full hour, minute and second in local time.
  • %y: two-digit year (00-99).
  • %Y: four-digit year (e.g. 1984).
  • %Z: abbreviation for time zone.

timespec_get()

`timespec_get() is used to convert the current time into nanoseconds (billionths of a second) from the time epoch.

``c int timespec_get ( struct timespec* ts, int base ) ;


``timespec_get()` accepts two arguments.

The first argument is a pointer to the struct timespec structure, which holds the converted time information. struct timespec has the following structure.

```c
struct timespec {
time_t tv_sec; // number of seconds
long tv_nsec; // nanoseconds
};

The second parameter is an integer indicating the starting point of the time calculation. The standard gives only one possible value, the macro TIME_UTC, which indicates the number of seconds to the time epoch to be returned.

Here is an example.

struct timespec ts;

timespec_get(&ts, TIME_UTC);

// 1614581530 s, 806325800 ns
printf("%ld s, %ld ns\n", ts.tv_sec, ts.tv_nsec);

double float_time = ts.tv_sec + ts.tv_nsec/1000000000.0;

// 1614581530.806326 seconds since epoch
printf("%f seconds since epoch\n", float_time);

clock()

The clock() function returns the CPU clock period from the start of program execution to the current time. A clock period is equal to the reciprocal of the CPU frequency, for example if the CPU frequency is 1G Hz, meaning that the clock signal can change 10^9 times in 1 second, then each clock period is 10^-9 seconds.

clock_t clock(void);

The `clock() function returns a number indicating the number of CPU clock cycles from the start of the program to the present. The type of this value is clock_t, which is generally of type long int.

To convert this value to seconds, it should be divided by the constant CLOCKS_PER_SEC (clock cycles per second), which is also defined by time.h.

printf("CPU time: %f\n", clock() / (double)CLOCKS_PER_SEC);

The above example outputs the number of seconds it took for the program to run from the start to this line.

The clock() function returns -1 if the computer is unable to provide CPU time, or if the return value is too large to be represented by a clock_t type.

To find out the exact time spent on an operation, call clock() twice and then subtract the return value from the two times.

clock_t start = clock();

// ... Execute some operation

clock_t end = clock();

long double seconds = (float)(end - start) / CLOCKS_PER_SEC;